package com.xncoding.pos.service;

import cn.hutool.core.date.DateUtil;
import com.google.common.util.concurrent.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalTime;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: bo
 * @create: 2024-08-28 14:40
 */
@Slf4j
@Service
public class GuavaAsyncTest {
    static ExecutorService executorService = Executors.newFixedThreadPool(5);

    /**
     * * ListenableFuture是对原有Future的增强，
     * * 可以用于监听Future任务的执行状况，是执行成功还是执行失败，并提供响应的接口用于对不同结果的处理。
     */
    public void futureTest() {
        log.info("GuavaAsyncTest-----打印日志------{}", DateUtil.now());
        ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);

        ListenableFuture<Integer> listenableFuture = listeningExecutorService.submit(() -> {
            log.info("执行了callable...{}", DateUtil.now());
            TimeUnit.SECONDS.sleep(3);
            return 1;
        });

        Futures.addCallback(listenableFuture, new FutureCallback<Integer>() {
            @Override
            public void onSuccess(Integer result) {
                // 当异步任务成功完成时，这里会被调用
                // 异步任务执行成功后的回调方法
                log.info(Thread.currentThread().getName() + ":异步任务执行成功，结果是：" + result + ",时间：" + LocalTime.now());
                //收到回调结果后，建议关注线程池，否则监听回调程序会一直阻塞，不会结束；
                // listeningExecutorService.shutdown();
            }

            @Override
            public void onFailure(Throwable t) {
                // 异常处理
                log.error("异常信息:{}", t.getMessage());
                t.printStackTrace();
            }
        }, listeningExecutorService);

    }


    /**
     * 组合多个异步任务
     * 。Guava的Futures.allAsList或者Futures.successfulAsList就是为这种场景设计的。
     * 这些方法允许咱们将多个ListenableFuture实例组合成一个，当所有的Future都完成时，组合后的Future也会完成。
     */
    public void manyTest() {
        ListeningExecutorService service = MoreExecutors.listeningDecorator(executorService);

        ListenableFuture<String> future1 = service.submit(() -> {
            // 模拟异步操作
            Thread.sleep(1000);
            return "任务1完成";
        });

        ListenableFuture<String> future2 = service.submit(() -> {
            // 模拟另一个异步操作
            Thread.sleep(1500);
            return "任务2完成";
        });

        // 将两个Future组合成一个
        ListenableFuture<List<String>> allFutures = Futures.allAsList(future1, future2);

        Futures.addCallback(allFutures, new FutureCallback<List<String>>() {
            @Override
            public void onSuccess(List<String> result) {
                // 当所有任务都成功完成后，这里会被调用
                result.forEach(System.out::println);
            }

            @Override
            public void onFailure(Throwable thrown) {
                // 如果任一任务失败，这里会被调用
                thrown.printStackTrace();
            }
        }, service);


    }

}
